package netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import netty.ObjectCodec;
import netty.SpringBootNettyServerApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class NettyServerListenner
{
	//创建bootstrap
	ServerBootstrap sbt = new ServerBootstrap();

	EventLoopGroup boss = new NioEventLoopGroup();

	EventLoopGroup work = new NioEventLoopGroup();

	private int port = 9999;

	@Autowired
	private ServerChannelHandlerAdapter serverChannelHandlerAdapter;

	@PostConstruct
	public void start()
	{
		new Thread()
		{
			public void run()
			{
				sbt.group(boss, work);
				//设置服务处理类
				sbt.channel(NioServerSocketChannel.class);
				try
				{
					//设置事件处理
					sbt.childHandler(new ChannelInitializer<SocketChannel>()
					{
						@Override
						protected void initChannel(SocketChannel ch)
							throws Exception
						{
							ChannelPipeline pipeline = ch.pipeline();
							pipeline.addLast(new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2));
							pipeline.addLast(new LengthFieldPrepender(2));
							pipeline.addLast(new ObjectCodec());
							pipeline.addLast(serverChannelHandlerAdapter);
						}
					});
					System.out.println("服务器启动，监听 @" + port + " ....");
					ChannelFuture f = sbt.bind(port).sync();
					f.channel().closeFuture().sync();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
					boss.shutdownGracefully();
					work.shutdownGracefully();
				}
			}

			;
		}.start();
	}

	//关闭前执行最后方法
	@PreDestroy
	public void close()
	{
		System.out.println("关闭服务器....");
		boss.shutdownGracefully();
		work.shutdownGracefully();
	}

	public void setChanneHandlerAdapter(ServerChannelHandlerAdapter serverChannelHandlerAdapter)
	{
		this.serverChannelHandlerAdapter = serverChannelHandlerAdapter;
	}

}
